package com.sxkiler.demo.rpc.server;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.sxkiler.demo.rpc.model.MessageContext;
import com.sxkiler.demo.rpc.model.Request;
import com.sxkiler.demo.rpc.model.Response;
import com.sxkiler.demo.utils.BeanUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.lang.reflect.Method;
import java.util.Random;

public class RpcServerHandler extends ChannelInboundHandlerAdapter {

    public RpcServerHandler() {
        super();
    }


    @Override
    public void channelRead(ChannelHandlerContext channelHandlerContext, Object msg) throws Exception {
        System.out.println("============收到来自客户端的消息 ====== " + msg);
        if (!(msg instanceof MessageContext)){
            return;
        }
        MessageContext reqContext = (MessageContext)msg;
        Object context = reqContext.getContext();
        Request request = JSON.parseObject(JSONObject.toJSONString(context), Request.class);//拿到消息体内的请求数据
        //将参数值和参数类型匹配对应
        Class<?>[] parameterType = request.getParameterType();
        Object[] parameterValue = request.getParameterValue();
        //由于参数值是通过json转换的，这边拿到的参数值全是JSONObject类型。所以需要将参数值按照参数类型重新转换一遍。
        if (parameterType.length == parameterValue.length){
            for (int i = 0; i < parameterValue.length; i++) {
                Object o = JSON.parseObject(JSONObject.toJSONString(parameterValue[i]), parameterType[i]);
                parameterValue[i] = o;
            }
        }
        System.out.println(context.getClass().getName());
        Object result = null ;
//        Class<?> aClass = Class.forName(request.getClassName());
        //先判断bean容器是否为空，如果为空则可以拿到请求参数的类名（全限定名）反射去创建对象
        Object o = BeanUtils.getApplicationBean(request.getServiceNameByAnnotated());
        //根据请求传的bean的name去bean容器里查，没查到则通过类全限定名反射创建对象
        if (o == null){
            System.out.println("beans里没找到实例");
            channelHandlerContext.writeAndFlush(new MessageContext(String.valueOf(new Random().nextInt(9999)),false,new Response(true,new Object(),Object.class)));
            return;
        }
        try{
            Method method = o.getClass().getMethod(request.getMethodName(), request.getParameterType());
            Class<?> returnType = method.getReturnType();
            Object invoke = method.invoke(o, request.getParameterValue());
            if (returnType.isInstance(invoke)){//将调用结果转换为方法返回类型。
                result = returnType.cast(invoke);
            }
            System.out.println("调用完成，返回结果："+(result==null?"":result.toString()));
            channelHandlerContext.writeAndFlush(new MessageContext(reqContext.getMessageId(),true,new Response(true,result,returnType)));
        }catch (Exception ex){
            channelHandlerContext.writeAndFlush(new MessageContext(reqContext.getMessageId(),false,null));
        }



    }

    @Override
    public void exceptionCaught(ChannelHandlerContext channelHandlerContext, Throwable cause) throws Exception {
        System.out.println("发生了异常");
        cause.printStackTrace();
        channelHandlerContext.writeAndFlush(new MessageContext());
        channelHandlerContext.close();
    }


}

